﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Water.Architecture2.EntityXML;
using System.Reflection;
using System.Data;
using Water.Web.Prompt;

namespace Water.Architecture2.Model
{
    [Serializable]
    public class BaseEntity
    {
        #region === 私有字段
        private Hashtable ht_propertiesValue = new Hashtable();//存储实体对象值转换为Hashtable
       
        private EntityMapping map;
        #endregion

        public BaseEntity()
        {
            map = EntityMappingContainer.Get(this.GetType().ToString());
        }


        #region Properties
        internal string Table
        {
            get { return map.Table; }
        }
        internal string View
        {
            get { return map.View; }
        }
        internal string Sql
        {
            get { return map.Sql; }
        }
        internal bool Subquery
        {
            get
            {
                return map.Subquery;
            }
        }
        internal string DefaultOrderByExpress
        {
            get { return map.DefaultOrderByExpress; }
        }
        internal string ConnectionStringName
        {
            get { return map.ConnectionStringName; }
        }
        internal bool QueryOnly
        {
            get { return map.QueryOnly; }
        }


        internal List<string> UpdateIgnoreFields
        {
            get { return map.UpdateIgnoreFields; }
        }
        internal List<string> InsertIgnoreFields
        {
            get { return map.InsertIgnoreFields; }
        }


        internal string PrimaryKeys
        {
            get { return map.PrimaryKeys; }
        }
        internal List<string> PrimaryKeyList
        {
            get { return map.PrimaryKeyList; }
        }

        internal string AllFields
        {
            get { return map.AllFields; }
        }
        internal List<string> AllFieldList
        {
            get { return map.AllFieldList; }
        }
        internal List<string> AllPropertitiesList
        {
            get { return map.AllPropertitiesList; }
        }

        internal List<PropertyNode> PropertyNodes
        {
            get { return map.PropertyNodes; }
        }
        internal List<PropertyNode> KeyProertyNodes
        {
            get { return map.KeyProertyNodes; }
        }
        internal List<PropertyNode> RefProertyNodes
        {
            get { return map.RefProertyNodes; }
        }


        internal Dictionary<string,Type> PropertiesType
        {
            get { return map.PropertiesType; }
        }
        internal Dictionary<string, Type> ColumnsType
        {
            get { return map.ColumnsType; }
        }
        internal Dictionary<string, string> PropertieColumnsMap
        {
            get { return map.PropertieColumnsMap; }
        }
        internal Dictionary<string, string> DirectPropertieColumnsMap
        {
            get { return map.DirectPropertieColumnsMap; }
        }
        internal Dictionary<string, string> RefPropertieColumnsMap
        {
            get { return map.RefPropertieColumnsMap; }
        }
        internal string BaseQuerySql
        {
            get { return map.BaseQuerySql; }
        }

        internal Hashtable PropertiesValue
        {
            get { return this.ht_propertiesValue.Count == 0 ? GetPropertiesValue() : this.ht_propertiesValue; }
        }

        internal Dictionary<string, string> AutoGenerators
        {
            get { return map.AutoGenerators; }
        }

        internal string DalClass
        {
            get { return map.DalClass; }
        }
        internal string DalAssembly
        {
            get { return map.DalAssembly; }
        }

        private DataSet entityStructure;

        internal DataSet EntityStructure
        {
            get
            {
                if (entityStructure == null)
                    entityStructure = this.CreateEntityStructure();
                return this.entityStructure;
            }
        }
        #endregion

        /// <summary>
        /// 实体对象转换为Hashtable，键[key]为属性名，值[value]为属性对应的值。
        /// </summary>
        /// <returns><c>Hashtable</c></returns>
        protected virtual Hashtable GetPropertiesValue()
        {
            if (this.ht_propertiesValue.Count == 0)
            {
                PropertyInfo[] pros = this.GetType().GetProperties();
                for (int i = 0; i < pros.Length; i++)
                {
                    Type tp = pros[i].PropertyType;
                    object objValue = pros[i].GetValue(this, null);
                    objValue = (objValue == null ? DBNull.Value : objValue);
                    string objName = pros[i].Name.ToUpper();
                    if (!ht_propertiesValue.ContainsKey(objName))
                        ht_propertiesValue.Add(objName, objValue);
                }
            }
            return ht_propertiesValue;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            Hashtable ht_propertiesValue = this.GetPropertiesValue();
            foreach (DictionaryEntry item in ht_propertiesValue)
            {
                sb.Append(item.Key + ":" + item.Value + " ");
            }
            return sb.ToString();
        }



        internal DataSet CreateEntityStructure()
        {
            DataTable dt = new DataTable(this.Table);
            DataSet ds = new DataSet();
            dt.Columns.Add("NAME", typeof(System.String));
            dt.Columns.Add("COLUMN", typeof(System.String));
            dt.Columns.Add("TABLE", typeof(System.String));
            dt.Columns.Add("PROMPT", typeof(System.String));

            foreach (PropertyNode propertyNode in this.PropertyNodes)
            {
                switch (propertyNode.NodeType)
                {
                    case PropertyNodeType.KeyProperty:
                    case PropertyNodeType.Property:
                        DataRow dr = dt.NewRow();
                        dr["NAME"] = propertyNode.Name.ToUpper();
                        dr["COLUMN"] = propertyNode.Column.ToUpper();
                        dr["TABLE"] = this.Table.ToUpper();
                        dr["PROMPT"] = "";//PromptProxy.GetPromptDesc(this.Table.ToUpper() + "." + propertyNode.Column);
                        dt.Rows.Add(dr);
                        break;
                    case PropertyNodeType.RefProperty:
                        EntityMapping refMap = EntityMappingContainer.Get(propertyNode.RefEntity);
                        string[] refDisplayProperties = propertyNode.RefDisplayProperty.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string pro in refDisplayProperties)
                        {
                            string[] _temp = pro.ToUpper().Split(new string[] { " AS " }, StringSplitOptions.RemoveEmptyEntries);
                            int _count = _temp.Length;
                            string _pro=string.Empty;
                            string _refCol = string.Empty;
                            //string _refType;
                           // string _as;
                            if (_count > 0)
                            {
                                _pro = _temp[0].Trim();
                                _refCol = refMap.PropertieColumnsMap[_pro];
                                //_refType=
                                /*if (_count > 1)
                                    _as = _temp[1].Trim();
                                else
                                    _as = _pro;*/
                            }
                            DataRow dr1 = dt.NewRow();
                            dr1["NAME"] = _pro;
                            dr1["COLUMN"] = _refCol;
                            dr1["TABLE"] = refMap.Table.ToUpper();
                            dr1["PROMPT"] =""; //PromptProxy.GetPromptDesc(refMap.Table.ToUpper() + "." + _refCol);
                            dt.Rows.Add(dr1);
                        }
                        break;
                    default:
                        break;
                        
                }
                //dt.Rows.Add(dr);
            } 
            ds.Tables.Add(dt);
            return ds;
        }

    }
}
